home *** CD-ROM | disk | FTP | other *** search
- /*
- * Routine for processing the keyboard input.
- *
- * Copyright (C) 1995 Philip VanBaren
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <ctype.h>
- #include <string.h>
- #include <math.h>
- #include <bios.h>
-
- #include "freq.h"
- #include "fft.h"
- #include "extern.h"
- #include "display.h"
-
- int display_peak = 0; /* Flag for displaying the peak information */
- int help_mode = 0; /* Flag indicating help mode 0 (off), 1, or 2 */
- int dtmf_mode = 0; /* Flag indicating DTMF mode */
- int ctcss_mode = 0; /* Flag indicating CTCSS mode */
- int log_mode = 0; /* Flag indicating LogFile mode */
- int gen_ctcss = CTCSS_MAX; /* generated CTCSS frequency number
- * (init to none) */
- double err_ctcss;
- int bw_mode = 0; /* Flag indicating a Black/White palette */
- int freeze = 0; /* Flag indicating a paused display */
- float freq_scalefactor = 1.0; /* Scalefactor for increasing the
- * horizonal scale */
- float freq_base = 0.0; /* Base frequency for the display */
- int bin = 0; /* Bin number for cursor display */
- int mic_level = 0; /* Storage for mic input mixer level (0-100) */
- int ext_level = 0; /* Storage for ext input mixer level (0-100) */
- int int_level = 0; /* Storage for int input mixer level (0-100) */
- int i; /* general miscelaneous */
- FILE *log_file; /* file pointer of the log_file */
-
- void
- cleanup_vga( void )
- {
- /*
- * Clean up VGA registers so Borland libraries work again.
- */
- outportb( 0x3c4, 2 );
- outportb( 0x3c5, 0x0f ); /* Use all bit planes */
- }
-
- void
- setup_vga( void )
- {
- /*
- * Set up VGA registers for fast graphics display
- */
- outportb( 0x3ce, 1 );
- outportb( 0x3cf, 0 ); /* Disable set/reset for all planes */
- outportb( 0x3ce, 3 );
- outportb( 0x3cf, 0 ); /* No rotate, just write data */
- outportb( 0x3ce, 4 );
- outportb( 0x3cf, 3 ); /* Read from bit plane 3 */
- outportb( 0x3ce, 5 );
- outportb( 0x3cf, inportb( 0x3cf ) & 0x70 ); /* Read and write direct to
- * memory */
- outportb( 0x3ce, 8 );
- outportb( 0x3cf, 0xff ); /* Allow modification of all bits */
- outportb( 0x3c4, 2 );
- outportb( 0x3c5, 12 ); /* Use bit planes 2 and 3 */
- }
-
- void
- draw_threshold_level( int color )
- {
- int y;
-
- if ( threshold_level < 0 )
- threshold_level = 0;
- if ( threshold_level > ys )
- threshold_level = ys;
- y = ( WINDOW_BOTTOM - WINDOW_TOP ) * threshold_level / ys;
- y = ( WINDOW_BOTTOM ) - y;
- draw_line( WINDOW_LEFT - 1, y, WINDOW_RIGHT + 1, y, color );
- }
-
- void
- input_text( char *text, int maxlen, int x, int y )
- {
- /*
- * Input a line of text using graphical display at (x,y) Maximum length
- * allowed for input is given by maxlen The input begins with the current
- * contents of text, so this must be initialized before calling the
- * routine.
- */
- int c = 0;
- int count;
- char ach[3];
- ach[1] = '_';
- ach[2] = 0;
-
- draw_text_left( x, y, text );
- count = strlen( text );
- x += count * _font_width;
- draw_text_left( x, y, "_" );
-
- while ( ( c != 0x0d ) && ( c != 0x0a ) )
- {
- c = draw_getch( );
-
- if ( ( ( c == 0x08 ) || ( c == 0x7f ) ) && count )
- {
- count--;
- x -= _font_width;
- draw_bar( x, y - 1, x + 2 * _font_width, y + _font_height, 0 );
- draw_text_left( x, y, "_" );
- }
- else if ( count < ( maxlen - 1 ) )
- {
- if ( ( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' )
- || c == '.' || c == '\\' || c == '/' || c == ':'
- || c == '*' || c == '#' || c == '-' )
- {
- draw_bar( x, y - 1, x + _font_width, y + _font_height, 0 );
-
- ach[0] = c;
- text[count] = c;
- draw_text_left( x, y, ach );
- count++;
- x += _font_width;
- }
- }
- if ( c == 0x1b )
- {
- count = 0;
- break;
- }
- }
- text[count] = 0;
- }
-
- void
- update_display( void )
- {
- /* Update the frequency and amplitude information displayed while */
- /* the input is frozen. */
-
- char ach[100];
- double re, im;
- double amp, db;
-
- int bri = BitReversed[bin];
- re = fftdata[bri];
- im = fftdata[bri + 1];
-
- amp = sqrt( re * re + im * im ) / 32768.0;
-
- if ( amp != 0 )
- db = 20 * log10( amp );
- else
- db = -100;
-
- draw_bar( 0, 21, 160, 71, 0 );
- sprintf( ach, " Freq: %7.5g Hz ", ( double ) bin * SampleRate / fftlen );
- draw_text_left( 0, 22, ach );
- sprintf( ach, " Amp: %7.5g ", amp );
- draw_text_left( 0, 34, ach );
- sprintf( ach, " %7.5g db ", db );
- draw_text_left( 0, 46, ach );
- }
-
-
- void
- highlight( int on )
- {
- /* Turn highlighting of a specified bin on the display on (1) or off (0) */
-
- int pos;
- double freq = ( double ) bin * ( double ) SampleRate / fftlen;
- if ( logfreq )
- pos = floor( log( freq / freq_base ) / log( fftlen / 2 ) * freq_scalefactor * ( double ) ( WINDOW_RIGHT - WINDOW_LEFT ) + 0.5 );
- else
- pos = floor( ( freq - freq_base ) * ( double ) ( WINDOW_RIGHT - WINDOW_LEFT ) / ( double ) SampleRate * freq_scalefactor * 2.0 + 0.5 );
-
- if ( on )
- {
- draw_line( WINDOW_LEFT + pos, WINDOW_TOP, WINDOW_LEFT + pos, lasty[pos], DARK_HIGHLIGHT );
- draw_line( WINDOW_LEFT + pos, lasty[pos], WINDOW_LEFT + pos, WINDOW_BOTTOM, LIGHT_HIGHLIGHT );
- }
- else
- {
- draw_line( WINDOW_LEFT + pos, WINDOW_TOP, WINDOW_LEFT + pos, lasty[pos], 0 );
- draw_line( WINDOW_LEFT + pos, lasty[pos], WINDOW_LEFT + pos, WINDOW_BOTTOM, GRAPH_COLOR );
- }
- }
-
- void
- help_freze( void )
- {
- draw_bar( WINDOW_LEFT - 5, MGY - 40, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_centered( MGX, MGY - 12, "Use arrows to move, Shift_arrows, Home & End to move quickly" );
- draw_text_centered( MGX, MGY, "Enter to save to disk, Space to continue" );
- }
-
- int
- process_input( int c, int repetitions )
- {
- /* Process any keyboard input received by the program */
- char ach[50];
- int i;
-
- if ( c == 0 )
- return ( 0 );
-
- if ( freeze )
- highlight( 0 );
-
- if ( c == ' ' ) /* Toggle freeze mode on/off */
- {
- freeze = !freeze;
- if ( freeze )
- {
- if ( help_mode )
- {
- help_mode = 0;
- update_header( );
- }
- if ( ( double ) bin < freq_base * fftlen / SampleRate )
- bin = ceil( freq_base * fftlen / SampleRate );
- if ( ( double ) bin > maxfreq * fftlen / SampleRate )
- bin = floor( maxfreq * fftlen / SampleRate );
-
- help_freze( );
-
- update_display( );
- }
- else
- {
- draw_bar( 0, 21, 160, 71, 0 );
- update_header( );
- }
- }
- if ( dtmf_mode || ctcss_mode )
- {
- if ( c == PG_UP )
- {
- draw_threshold_level( 0 );
- threshold_level += ys / 50;
- draw_threshold_level( TEXT_COLOR );
- }
- if ( c == PG_DN )
- {
- draw_threshold_level( 0 );
- threshold_level -= ys / 50;
- draw_threshold_level( TEXT_COLOR );
- }
- if ( c == 'G' || c == 'g' )
- {
- log_mode = !log_mode;
- if ( log_mode )
- {
- log_file = fopen( "dtmf_fft.log", "a" );
- if ( log_file == NULL )
- log_mode = 0;
- }
- else
- {
- fclose( log_file );
- }
- update_header( );
- }
- }
- if ( ( c == 'D' || c == 'd' ) && !ctcss_mode ) /* Toggle DTMF mode */
- {
- dtmf_mode = !dtmf_mode;
- if ( dtmf_mode )
- {
- halt_soundcard( );
- EndFFT( );
- SampleRate = 5000L;
- fftlen = 128;
- logfreq = 0;
- freq_scalefactor = 1.0;
- InitializeFFT( fftlen );
- compute_window_function( );
- /* Flush the buffers */
- for ( i = 0; i < fftlen / 2; i++ )
- displayval[i] = 0;
- for ( i = 0; i < fftlen; i++ )
- fftdata[i] = 0;
- /* Re-initialize the display */
- p_dtmf = 0;
- dtmf_nr[0] = 0;
- setup_xscale( );
- update_header( );
- reset_soundcard( );
- }
- else
- {
- update_header( );
- draw_threshold_level( 0 );
- }
- }
- else if ( ( c == 'T' || c == 't' ) && !dtmf_mode ) /* Toggle CTCSS mode */
- {
- ctcss_mode = !ctcss_mode;
- if ( ctcss_mode )
- {
- halt_soundcard( );
- EndFFT( );
- SampleRate = 5000L;
- fftlen = 2048;
- logfreq = 1;
- freq_scalefactor = 1.0;
- InitializeFFT( fftlen );
- compute_window_function( );
- /* Flush the buffers */
- for ( i = 0; i < fftlen / 2; i++ )
- displayval[i] = 0;
- for ( i = 0; i < fftlen; i++ )
- fftdata[i] = 0;
- p_dtmf = 0;
- dtmf_nr[0] = 0;
- /* Re-initialize the display */
- setup_xscale( );
- update_header( );
- reset_soundcard( );
- }
- else
- {
- update_header( );
- draw_threshold_level( 0 );
- }
- }
- else if ( freeze )
- {
- /* Keys only valid in freeze-display */
- if ( ( c == 0x0d ) || ( c == 0x0a ) ) /* <CR> saves the spectrum
- * data to a file */
- {
- char filename[30];
- draw_bar( WINDOW_LEFT - 5, MGY - 1, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_left( MGX - 156, MGY, "File in which to save this spectrum:" );
-
- filename[0] = 0;
- input_text( filename, sizeof( filename ), MGX + 140, MGY );
- if ( filename[0] != 0 )
- {
- clock_t clk;
- FILE *fp = fopen( filename, "w" );
- if ( fp )
- {
- for ( i = 0; i < fftlen / 2; i++ )
- {
- double re, im;
- re = fftdata[BitReversed[i]] / 32768.0;
- fprintf( fp, "%g\t%g\n", ( double ) i / ( double ) fftlen
- * ( double ) SampleRate, re );
- }
- fclose( fp );
- sprintf( ach, "Spectrum data saved in %s", filename );
- }
- else
- sprintf( ach, "Unable to open (%s)", filename );
-
- draw_bar( WINDOW_LEFT - 5, MGY - 1, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_centered( MGX, MGY, ach );
-
- clk = clock( );
- while ( !draw_getkey( ) && ( ( clock( ) - clk ) < CLOCKS_PER_SEC * 3 ) );
- }
- draw_bar( WINDOW_LEFT - 5, MGY - 13, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- help_freze( );
- }
- if ( c == LEFT_ARROW ) /* Move the cursor one bin left */
- if ( !( bioskey( 2 ) & 3 ) ) /* if no shift key is pressed */
- {
- double current;
- bin -= repetitions;
- if ( bin <= 0 )
- {
- if ( logfreq )
- bin = 1;
- else
- bin = 0;
- }
- current = ( double ) bin *( double ) SampleRate / ( double ) fftlen;
- if ( current < freq_base )
- {
- freq_base = current;
- /* Re-initialize the display */
- setup_xscale( );
- }
- update_display( );
- }
- else
- { /* Move the cursor 10 bins left */
- double current;
- bin -= 10 * repetitions;
- if ( bin <= 0 )
- {
- if ( logfreq )
- bin = 1;
- else
- bin = 0;
- }
- current = ( double ) bin *( double ) SampleRate / ( double ) fftlen;
- if ( current < freq_base )
- {
- freq_base = current;
- /* Re-initialize the display */
- setup_xscale( );
- }
- update_display( );
- }
- else if ( c == RIGHT_ARROW )/* Move the cursor one bin right */
- if ( !( bioskey( 2 ) & 3 ) ) /* if no shift key is pressed */
- {
- double current;
- bin += repetitions;
- if ( bin >= fftlen / 2 )
- bin = fftlen / 2 - 1;
- current = ( double ) bin *( double ) SampleRate / ( double ) fftlen;
- if ( current > maxfreq )
- {
- if ( logfreq )
- freq_base = current / exp( log( fftlen / 2 ) / freq_scalefactor );
- else
- freq_base = current - ( double ) SampleRate / ( freq_scalefactor * 2.0 );
- /* Re-initialize the display */
- setup_xscale( );
- }
- update_display( );
- }
- else
- {
- double current;
- bin += 10 * repetitions;
- if ( bin >= fftlen / 2 )
- bin = fftlen / 2 - 1;
- current = ( double ) bin *( double ) SampleRate / ( double ) fftlen;
- if ( current > maxfreq )
- {
- if ( logfreq )
- freq_base = current / exp( log( fftlen / 2 ) / freq_scalefactor );
- else
- freq_base = current - ( double ) SampleRate / ( freq_scalefactor * 2.0 );
- /* Re-initialize the display */
- setup_xscale( );
- }
- update_display( );
- }
- else if ( c == HOME ) /* Move the cursor to the lowest frequency */
- {
- if ( logfreq )
- bin = 1;
- else
- bin = 0;
- update_display( );
- if ( ( logfreq && ( freq_base > ( ( double ) SampleRate / ( double ) fftlen ) ) )
- || ( !logfreq && ( freq_base > 0 ) ) )
- {
- freq_base = 0;
- /* Re-initialize the display */
- setup_xscale( );
- }
- }
- else if ( c == END ) /* Move the cursor to the highest frequency */
- {
- bin = fftlen / 2 - 1;
- update_display( );
- if ( maxfreq < ( double ) SampleRate / 2 )
- {
- freq_base = SampleRate / 2;
- /* Re-initialize the display */
- setup_xscale( );
- }
- }
- }
- else if ( !dtmf_mode && !ctcss_mode )
- {
- /* Keys only valid in non-freeze display */
- if ( c == HOME ) /* Move the cursor to the lowest frequency */
- {
- if ( logfreq && ( freq_base > ( ( double ) SampleRate / ( double ) fftlen ) ) )
- {
- /* Re-initialize the display */
- freq_base = 0;
- setup_xscale( );
- }
- else if ( !logfreq && ( freq_base > 0 ) )
- {
- /* Re-initialize the display */
- freq_base = 0;
- setup_xscale( );
- }
- }
- else if ( c == END ) /* Move the cursor to the highest frequency */
- {
- if ( maxfreq < ( double ) SampleRate / 2 )
- {
- freq_base = SampleRate / 2;
- /* Re-initialize the display */
- setup_xscale( );
- }
- }
- else if ( c == 'H' || c == 'h' || c == '?' || c == '/' ) /* Toggle help mode */
- {
- help_mode++;
- if ( help_mode > 2 )
- help_mode = 0;
-
- if ( help_mode )
- show_help( );
- else
- update_header( );
- }
- else if ( c == 'F' || c == 'f' ) /* Change the FFT length */
- {
- halt_soundcard( );
- EndFFT( );
- if ( c == 'f' )
- {
- for ( i = 0; i < repetitions; i++ )
- {
- fftlen *= 2;
- if ( fftlen > MAX_LEN )
- fftlen = 8;
- }
- }
- else
- {
- for ( i = 0; i < repetitions; i++ )
- {
- fftlen /= 2;
- if ( fftlen < 8 )
- fftlen = MAX_LEN;
- }
- }
- InitializeFFT( fftlen );
- compute_window_function( );
- /* Flush the buffers */
- for ( i = 0; i < fftlen / 2; i++ )
- displayval[i] = 0;
- for ( i = 0; i < fftlen; i++ )
- fftdata[i] = 0;
- /* Re-initialize the display */
- setup_xscale( );
- if ( help_mode )
- show_help( );
- else
- update_header( );
- reset_soundcard( );
- }
- else if ( c == 'R' || c == 'r' ) /* Change the sampling rate */
- {
- char in[6];
- draw_bar( WINDOW_LEFT - 5, MGY - 1, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_left( MGX - 80, MGY, "Sampling rate: " );
-
- in[0] = 0;
- input_text( in, sizeof( in ), MGX + 40, MGY );
- if ( in[0] != 0 )
- {
- halt_soundcard( );
-
- SampleRate = atol( in );
- if ( SampleRate < 5000L )
- SampleRate = 5000L;
- if ( SampleRate > 88200L )
- SampleRate = 88200L;
-
- reset_soundcard( );
-
- /* Re-initialize the display */
- setup_xscale( );
- }
- if ( help_mode )
- show_help( );
- else
- update_header( );
- }
- }
-
- /* Keys valid in both freeze and non-freeze mode */
-
- if ( c == 'I' || c == 'i' )
- {
- char *p, *s;
- int valid;
-
- draw_bar( WINDOW_LEFT - 5, MGY - 40, WINDOW_RIGHT + 5, MGY + 8, 0 );
- draw_fontcolor( BORDER_COLOR );
- draw_text_left( WINDOW_LEFT, MGY - 12, "DTMF number to compose: " );
-
- dtmf_nr[0] = 0;
- input_text( dtmf_nr, 64, WINDOW_LEFT, MGY ); /* maximum 64 DTMF
- * numbers */
- draw_bar( WINDOW_LEFT - 5, MGY - 16, WINDOW_RIGHT + 5, MGY + 8, 0 );
- p = s = dtmf_nr;
- valid = 0;
- while ( *p != 0 )
- {
- if ( *p >= 'a' && *p <= 'd' )
- *p &= ~0x20; /* upper case */
- if ( !( *p >= '0' && *p <= '9' ) && !( *p >= 'A' && *p <= 'D' )
- && *p != '*' && *p != '#' )
- *p = '-';
- else
- valid = 1;
- if ( valid )
- *s++ = *p;
- p++;
- }
- while ( *--s == '-' )
- ;
- *++s = 0;
- update_header( );
- }
- else if ( c == 'A' || c == 'a' )
- {
- char str[10];
- int m = 0;
- int err;
- int old_ctcss;
-
- draw_bar( 0, 0, 639, 92, 0 );
- draw_fontcolor( TEXT_COLOR );
- draw_text_centered( ( WINDOW_LEFT + WINDOW_RIGHT ) / 2, 2,
- "Arrows to move (\033 \032 \030 \031) / Esc to exit / Enter when done" );
- draw_fontcolor( LABEL_COLOR );
- draw_text_left( WINDOW_LEFT, 15, "Choose a tone frequency:" );
- draw_fontcolor( TEXT_COLOR );
- draw_text_left( WINDOW_LEFT + 248, 15, "SPACE toggles" );
- draw_fontcolor( GRAPH_COLOR );
- draw_text_left( WINDOW_LEFT + 366, 15, "active" );
- draw_fontcolor( TEXT_COLOR );
- draw_text_left( WINDOW_LEFT + 426, 15, "/" );
- draw_fontcolor( BORDER_COLOR );
- draw_text_left( WINDOW_LEFT + 440, 15, "inactive" );
- old_ctcss = gen_ctcss;
- do
- {
- switch ( m )
- {
- case ' ':
- if ( gen_ctcss < CTCSS_MAX )
- if ( gen_ctcss < 32 )
- ctcss_act1 ^= 1L << gen_ctcss;
- else
- ctcss_act2 ^= 1L << ( gen_ctcss - 32 );
- break;
- case LEFT_ARROW:
- if ( gen_ctcss >= 1 )
- gen_ctcss--;
- break;
- case RIGHT_ARROW:
- if ( gen_ctcss < CTCSS_MAX )
- gen_ctcss++;
- break;
- case UP_ARROW:
- if ( gen_ctcss >= 10 )
- gen_ctcss -= 10;
- break;
- case DOWN_ARROW:
- if ( gen_ctcss <= CTCSS_MAX - 10 )
- gen_ctcss += 10;
- break;
- }
- for ( i = 0; i <= CTCSS_MAX; i++ )
- {
- if ( i == CTCSS_MAX )
- sprintf( str, "%s", "none" );
- else
- sprintf( str, "%5.1f", f_ctcss[i] );
- if ( i == gen_ctcss )
- if ( i < CTCSS_MAX &&
- ( i < 32 ? ctcss_act1 >> i : ctcss_act2 >> ( i - 32 ) ) & 1 )
- draw_fontcolor( TEXT_COLOR );
- else
- draw_fontcolor( LABEL_COLOR );
- else if ( i < CTCSS_MAX &&
- ( i < 32 ? ctcss_act1 >> i : ctcss_act2 >> ( i - 32 ) ) & 1 )
- draw_fontcolor( GRAPH_COLOR );
- else
- draw_fontcolor( BORDER_COLOR );
- draw_text_left( WINDOW_LEFT + ( i % 10 ) * 52, 29 + 11 * ( i / 10 ), str );
- }
- } while ( ( m = draw_getkey( ) ) != 0x0d && ( m != 0x1b ) );
-
- if ( m == 0x1b )
- gen_ctcss = old_ctcss;
- else
- {
- halt_soundcard( );
- err_ctcss = generate_CTCSS( gen_ctcss );
- reset_soundcard( );
- }
- draw_bar( 0, 0, 639, 92, 0 );
- update_header( );
- }
- else if ( c == TAB )
- {
- dtmf_mode = ctcss_mode = 0;
- draw_threshold_level( 0 );
- update_header( );
- if ( dtmf_nr[0] != 0 )
- {
- draw_fontcolor( TEXT_COLOR );
- draw_bar( WINDOW_LEFT - 5, MGY - 16, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_left( WINDOW_LEFT, MGY - 12, "Composing: " );
- halt_soundcard( );
- generate_DTMF( dtmf_nr );
- reset_soundcard( );
- update_header( );
- }
- }
- else if ( c == UP_ARROW )
- { /* Increase the vertical scale factor */
- if ( dtmf_mode || ctcss_mode )
- draw_threshold_level( 0 );
- {
- double last_ys = ys;
- for ( i = 0; i < repetitions; i++ )
- {
- if ( ys > 0.15 )
- {
- ys -= 0.1;
- }
- else if ( ys > 0.01 )
- {
- ys -= 0.01;
- if ( ys < 0.01 )
- ys = 0.01;
- }
- }
- if ( ys != last_ys )
- setup_linscales( );
- }
- if ( dtmf_mode || ctcss_mode )
- draw_threshold_level( TEXT_COLOR );
- amplitude_scale( );
- }
- else if ( c == DOWN_ARROW )
- { /* Decrease the vertical scale factor */
- if ( dtmf_mode || ctcss_mode )
- draw_threshold_level( 0 );
- {
- double last_ys = ys;
- for ( i = 0; i < repetitions; i++ )
- {
- if ( ys < 0.095 )
- {
- ys += 0.01;
- }
- else if ( ys < 2.00 )
- {
- ys += 0.1;
- if ( ys > 2.0 )
- ys = 2.0;
- }
- }
- if ( ys != last_ys )
- setup_linscales( );
- }
- if ( dtmf_mode || ctcss_mode )
- draw_threshold_level( TEXT_COLOR );
- amplitude_scale( );
- }
- else if ( ( c == '<' ) || ( c == CTRL_LEFT ) || ( c == ALT_LEFT ) )
- { /* Decrease the horizontal scale factor */
- if ( freq_scalefactor > 1.0 )
- {
- for ( i = 0; ( freq_scalefactor > 1.0 ) && ( i < repetitions ); i++ )
- {
- freq_scalefactor *= 0.84089641525371; /* 1/(2^0.25) */
- if ( logfreq )
- freq_base *= exp( log( fftlen / 2 ) * 0.07955179237314 / freq_scalefactor );
- else
- freq_base -= ( double ) SampleRate *0.03977589618657 / freq_scalefactor;
- }
- /* Re-initialize the display */
- if ( freeze )
- {
- double current = ( double ) bin * ( double ) SampleRate / ( double ) fftlen;
- xrange_check( );
- if ( current < freq_base )
- {
- freq_base = current;
- }
- if ( current > maxfreq )
- {
- if ( logfreq )
- freq_base = current / exp( log( fftlen / 2 ) / freq_scalefactor );
- else
- freq_base = current - ( double ) SampleRate / 2.0 / freq_scalefactor;
- }
- }
- setup_xscale( );
- }
- }
- else if ( ( c == '>' ) || ( c == CTRL_RIGHT ) || ( c == ALT_RIGHT ) )
- { /* Increase the horizontal scale factor */
- if ( freq_scalefactor < 16.0 )
- {
- for ( i = 0; ( freq_scalefactor < 16.0 ) && ( i < repetitions ); i++ )
- {
- if ( logfreq )
- freq_base *= exp( log( fftlen / 2 ) * 0.07955179237314 / freq_scalefactor );
- else
- freq_base += ( double ) SampleRate *0.03977589618657 / freq_scalefactor;
- freq_scalefactor *= 1.18920711500272; /* 2^0.25 */
- }
-
- /* Re-initialize the display */
- if ( freeze )
- {
- double current = ( double ) bin * ( double ) SampleRate / ( double ) fftlen;
- xrange_check( );
- if ( current < freq_base )
- {
- freq_base = current;
- }
- if ( current > maxfreq )
- {
- if ( logfreq )
- freq_base = current / exp( log( fftlen / 2 ) / freq_scalefactor );
- else
- freq_base = current - ( double ) SampleRate / 2.0 / freq_scalefactor;
- }
- }
- setup_xscale( );
- }
- }
- else if ( ( c == ',' ) || ( c == LEFT_ARROW ) )
- { /* Shift the horizontal display to the right */
- if ( maxfreq < ( double ) SampleRate / 2 )
- {
- for ( i = 0; ( i < repetitions ) && ( maxfreq < ( double ) SampleRate / 2 ); i++ )
- {
- if ( logfreq )
- freq_base *= exp( log( fftlen / 2 ) / ( 8.0 * freq_scalefactor ) );
- else
- freq_base += ( double ) SampleRate / ( 16.0 * freq_scalefactor );
- xrange_check( );
- }
- /* Re-initialize the display */
- if ( freeze )
- {
- double current = ( double ) bin * ( double ) SampleRate / ( double ) fftlen;
- if ( current < freq_base )
- {
- bin = ceil( freq_base / ( double ) SampleRate * ( double ) fftlen );
- update_display( );
- }
- }
- setup_xscale( );
- }
- }
- else if ( ( c == '.' ) || ( c == RIGHT_ARROW ) )
- { /* Shift the horizontal display to the left */
- if ( ( logfreq && ( freq_base > ( ( double ) SampleRate / ( double ) fftlen ) ) )
- || ( !logfreq && ( freq_base > 0 ) ) )
- {
- for ( i = 0; i < repetitions; i++ )
- {
- if ( ( logfreq && ( freq_base > ( ( double ) SampleRate / ( double ) fftlen ) ) )
- || ( !logfreq && ( freq_base > 0 ) ) )
- {
- if ( logfreq )
- freq_base /= exp( log( fftlen / 2 ) / ( 8.0 * freq_scalefactor ) );
- else
- freq_base -= ( double ) SampleRate / ( 16.0 * freq_scalefactor );
- }
- xrange_check( );
- }
- /* Re-initialize the display */
- if ( freeze )
- {
- double current = ( double ) bin * ( double ) SampleRate / ( double ) fftlen;
- if ( current > maxfreq )
- {
- bin = floor( maxfreq / ( double ) SampleRate * ( double ) fftlen );
- if ( bin >= fftlen / 2 )
- bin = fftlen / 2 - 1;
- update_display( );
- }
- }
- setup_xscale( );
- }
- }
- else if ( c == 'P' || c == 'p' ) /* Toggle peak display mode on/off */
- {
- display_peak = !display_peak;
- if ( display_peak )
- {
- draw_text_left( PKX - 64, PKY, "Peak at Hz" );
- }
- else
- {
- draw_bar( PKX - 64, PKY - 1, PKX + 79, PKY + _font_height, 0 );
- }
- }
- else if ( c == 'V' || c == 'v' ) /* Redraw the video display */
- {
- draw_bar( 0, 0, 639, 479, 0 );
-
- /* Refresh the video display */
-
- draw_rectangle( WINDOW_LEFT - 2, WINDOW_TOP - 2, WINDOW_RIGHT + 2, WINDOW_BOTTOM + 2, BORDER_COLOR );
- setup_xscale( );
- amplitude_scale( );
- if ( help_mode )
- show_help( );
- else
- update_header( );
- if ( display_peak )
- {
- draw_text_left( PKX - 64, PKY, "Peak at Hz" );
- }
- if ( freeze )
- {
- help_freze( );
- update_display( );
- }
- /* Reset the last-value contents */
- for ( i = 0; i < WINDOW_RIGHT - WINDOW_LEFT; i++ )
- lasty[i] = WINDOW_BOTTOM;
- }
- else if ( c == 'S' || c == 's' ) /* Save the current state to an INI
- * file */
- {
- draw_bar( WINDOW_LEFT, MGY - 1, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_left( MGX - 130, MGY, "Save the current state to: " );
- strncpy( ach, ini_file, 20 );
- input_text( ach, 20, MGX + 86, MGY );
- if ( ach[0] != 0 )
- {
- FILE *fp;
- strcpy( ini_file, ach );
- fp = fopen( ini_file, "w" );
- if ( fp )
- {
- fprintf( fp, "Soundcard: %d\n", Soundcard );
- fprintf( fp, "Sample rate: %ld\n", SampleRate );
- fprintf( fp, "FFT length: %d\n", fftlen );
- fprintf( fp, "Log freq scale: %d\n", logfreq );
- fprintf( fp, "Max amp: %g\n", ys );
- fprintf( fp, "Base frequency: %g\n", freq_base );
- fprintf( fp, "Frequency factor: %g\n", freq_scalefactor );
- fprintf( fp, "DTMF & CTCSS threshold level: %g\n", threshold_level );
- fprintf( fp, "DTMF delay (100 - 1000 ms): %d\n", 3 * dtmf_delay );
- fprintf( fp, "CTCSS active: 0x%08lX, 0x%08lX\n", ctcss_act1, ctcss_act2 );
- fprintf( fp, "Background color: %d,%d,%d\n", background.red, background.green, background.blue );
- fprintf( fp, "Clipping warning color: %d,%d,%d\n", warn.red, warn.green, warn.blue );
- fprintf( fp, "Graph color: %d,%d,%d\n", graph.red, graph.green, graph.blue );
- fprintf( fp, "Tick mark color: %d,%d,%d\n", tick.red, tick.green, tick.blue );
- fprintf( fp, "Axis label color: %d,%d,%d\n", label.red, label.green, label.blue );
- fprintf( fp, "Border color: %d,%d,%d\n", border.red, border.green, border.blue );
- fprintf( fp, "Text color: %d,%d,%d\n", text.red, text.green, text.blue );
- fprintf( fp, "Cursor upper color: %d,%d,%d\n", darkhl.red, darkhl.green, darkhl.blue );
- fprintf( fp, "Cursor lower color: %d,%d,%d\n", lighthl.red, lighthl.green, lighthl.blue );
- fclose( fp );
- }
- else
- {
- clock_t clk = clock( );
- sprintf( ach, "Unable to open %s", ini_file );
- draw_bar( WINDOW_LEFT - 5, MGY - 1, WINDOW_RIGHT + 5, MGY + _font_height, 0 );
- draw_text_centered( MGX, MGY, ach );
- while ( !draw_getkey( ) && ( ( clock( ) - clk ) < 3 * CLOCKS_PER_SEC ) );
- }
- }
- if ( help_mode )
- show_help( );
- else
- update_header( );
- if ( freeze )
- {
- help_freze( );
- update_display( );
- }
- }
- else if ( c == 'C' || c == 'c' ) /* Toggle Black/White palette on/off */
- {
- bw_mode = !bw_mode;
- if ( bw_mode )
- setbwpalette( );
- else
- setnormalpalette( );
- }
- else if ( c == 'L' || c == 'l' ) /* Toggle linear/logarithmic
- * frequency axis */
- {
- /*
- * Toggle between linear and logarithmic and equalizer frequency scale
- */
- logfreq = !logfreq;
-
- if ( freeze )
- {
- double current;
- if ( logfreq && ( bin == 0 ) )
- bin = 1;
- current = ( double ) bin *( double ) SampleRate / ( double ) fftlen;
- xrange_check( );
- if ( current < freq_base )
- {
- freq_base = current;
- }
- if ( current > maxfreq )
- {
- if ( !logfreq )
- freq_base = current - ( double ) SampleRate / 2.0 / freq_scalefactor;
- else
- freq_base = current / exp( log( fftlen / 2 ) / freq_scalefactor );
- }
- }
- setup_xscale( );
- }
- else if ( mixers )
- {
- if ( c == '[' ) /* External jack down */
- {
- ext_level -= 2 * repetitions;
- if ( ext_level < 0 )
- ext_level = 0;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", ext_level );
- draw_bar( LVX + 104, LVY - 1, LVX + 127, LVY + _font_height, 0 );
- draw_text_left( LVX + 104, LVY, ach );
- }
- set_mixer( MIXER_EXT, ext_level );
- }
- else if ( c == ']' ) /* External jack up */
- {
- ext_level += 2 * repetitions;
- if ( ext_level > 100 )
- ext_level = 100;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", ext_level );
- draw_bar( LVX + 104, LVY - 1, LVX + 127, LVY + _font_height, 0 );
- draw_text_left( LVX + 104, LVY, ach );
- }
- set_mixer( MIXER_EXT, ext_level );
- }
- else if ( c == '{' ) /* CD input down */
- {
- int_level -= 2 * repetitions;
- if ( int_level < 0 )
- int_level = 0;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", int_level );
- draw_bar( LVX + 168, LVY - 1, LVX + 191, LVY + _font_height, 0 );
- draw_text_left( LVX + 168, LVY, ach );
- }
- set_mixer( MIXER_INT, int_level );
- }
- else if ( c == '}' ) /* CD input up */
- {
- int_level += 2 * repetitions;
- if ( int_level > 100 )
- int_level = 100;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", int_level );
- draw_bar( LVX + 168, LVY - 1, LVX + 191, LVY + _font_height, 0 );
- draw_text_left( LVX + 168, LVY, ach );
- }
- set_mixer( MIXER_INT, int_level );
- }
- else if ( c == '(' ) /* Mic input down */
- {
- mic_level -= 2 * repetitions;
- if ( mic_level < 0 )
- mic_level = 0;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", mic_level );
- draw_bar( LVX + 32, LVY - 1, LVX + 55, LVY + _font_height, 0 );
- draw_text_left( LVX + 32, LVY, ach );
- }
- set_mixer( MIXER_MIC, mic_level );
- }
- else if ( c == ')' ) /* Mic input up */
- {
- mic_level += 2 * repetitions;
- if ( mic_level > 100 )
- mic_level = 100;
- if ( !help_mode )
- {
- sprintf( ach, "%3d", mic_level );
- draw_bar( LVX + 32, LVY - 1, LVX + 55, LVY + _font_height, 0 );
- draw_text_left( LVX + 32, LVY, ach );
- }
- set_mixer( MIXER_MIC, mic_level );
- }
- }
-
- if ( freeze )
- highlight( 1 );
-
- return ( c == 'E' || c == 'e' || c == 'Q' || c == 'q' || c == 0x1b );
- }
-